/*
 * This file is part of LangMan.
 *
 * LangMan is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * LangMan is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with LangMan.  If not, see <http://www.gnu.org/licenses/>.
 */

package langman.business.data.model;

import javafx.beans.InvalidationListener;
import javafx.beans.Observable;
import javafx.beans.property.*;
import javafx.collections.FXCollections;
import javafx.collections.ObservableMap;

import java.util.LinkedHashMap;

public final class Category implements InvalidationListener, Observable {
    private final StringProperty name = new SimpleStringProperty(this, "name");

    private final ObservableMap<String, Key> keys = FXCollections.observableMap(new LinkedHashMap<>());

    private final DoubleProperty completeness = new SimpleDoubleProperty();

    public Category(String name) {
        setName(name);
    }

    @Override
    public void addListener(InvalidationListener listener) {
        keys.addListener(listener);
        name.addListener(listener);
        completeness.addListener(listener);
    }

    @Override
    public void removeListener(InvalidationListener listener) {
        keys.removeListener(listener);
        name.removeListener(listener);
        completeness.removeListener(listener);
    }

    public double getCompleteness() {
        return completeness.get();
    }

    public String getName() {
        return name.get();
    }

    public void setName(String name) {
        this.name.set(name);
    }

    public ObservableMap<String, Key> getKeysUnmodifiable() {
        return new ReadOnlyMapWrapper<>(keys);
    }

    public void addKey(Key key) {
        keys.put(key.getKey(), key);
        key.addListener(this);
        invalidated(key);
    }

    public void removeKey(Key key) {
        keys.remove(key.getKey());
        key.removeListener(this);
        invalidated(key);
    }

    @Override
    public String toString() {
        return getName();
    }

    @Override
    public void invalidated(Observable observable) {
        double overallCompleteness = 0;
        for (Key key : keys.values()) {
            overallCompleteness += key.getCompleteness();
        }
        completeness.set(overallCompleteness / keys.size());
    }
}
